package test.core;

import java.lang.reflect.Method;
import java.util.Scanner;

/**
 * JAVA反射机制
 * 反射机制是java的动态机制，没有它就没有如今这么多java的框架。
 * 反射机制允许我们在程序【运行期间】再确定对象的实例化，方法的调用，属性的操作等。
 * 这使得程序的灵活度大大的提高，但是随之也带来了更多的开销和较慢的运行效率。
 * 因此反射机制也不能被过度的依赖。
 */
public class ReflectDemo1 {
    public static void main(String[] args) throws ClassNotFoundException {

        /*
            Class类
            Class类的每一个实例被成为"类对象"，用于描述被JVM加载的一个类。
            JVM在加载一个类时会先读取该类的.class文件随后实例化一个Class实例用于记录加载的类的一切信息
            比如:类名，有什么属性，方法，构造器等。
            每个被JVM加载的类都有且只有一个Class的实例与之对应。
            反射的第一步就是获取要操作的类的类对象，从而了解该类的内容，在程序运行期间再确定对其做什么操作。

            获取一个类的类对象方式主要有:
            1:类名.class
            例如:
                Class cls = String.class;//获取String类的类对象
                Class cls = int.class;//获取int的类对象（获取基本类型的类对象仅有这种方式）

            2:Class.forName(String className)
              通过指定类的完全限定名(包名.类名)的方式获取类对象

            3:使用类加载器ClassLoader形式
         */
        //获取String类的类对象
//        Class cls = String.class;
//        Class cls = ArrayList.class;
//        Class cls = Class.forName("java.lang.String");
        /*
            java.util.ArrayList     java.util.HashMap   java.lang.String    reflect.Person
            java.io.FileInputStream
         */
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入一个类的完全限定名:");
        String className = scanner.nextLine();
        Class cls = Class.forName(className);


        //获取的是完全限定名(包名.类名)
        String name = cls.getName();//获取的是当前类对象所表示的类的名字
        System.out.println(name);
        name = cls.getSimpleName();//仅获取类名
        System.out.println(name);
        //获取包名
        String packName = cls.getPackage().getName();
        System.out.println(packName);
        /*
            Method类:方法对象
            Method的每一个实例用于表示某个类中的某个特定方法
         */
        //通过类对象获取一个类中的所有公开方法
        Method[] methods = cls.getMethods();
        System.out.println(name+"类共有"+methods.length+"个公开方法");
        for(Method method : methods){
            System.out.println(method.getName());
        }
    }
}





